package com.rent.common.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import springfox.documentation.annotations.ApiIgnore;

import java.lang.reflect.Method;

/**
 * @Author zhang
 * @create 2022/9/17 14:28
 */
@Slf4j
@Aspect
@Component
public class RequestApiIgnoreAspect {

    /***
     * 定义controller切入点拦截规则：拦截标记SysLog注解和指定包下的方法
     * 2个表达式加起来才能拦截所有Controller 或者继承了BaseController的方法
     * \@annotation(top.tangyh.basic.annotation.log.SysLog) 解释：
     * 标记了@SysLog 注解的方法
     */
    @Pointcut("execution(public * com.rent.*.controller.*.*(..)) && @annotation(springfox.documentation.annotations.ApiIgnore)")
    public void requestAspect() {
    }

    /**
     * 执行方法之前
     *
     * @param joinPoint 端点
     */
    @Before(value = "requestAspect()")
    public void doBefore(JoinPoint joinPoint) {
        log.info("忽略请求切面开始");
        ApiIgnore apiIgnore = getTargetAnnotation(joinPoint);
        if (apiIgnore == null) return;
        log.info("忽略:{}", apiIgnore.value());
//        Asserts.fail("操作失败");
    }

    /**
     * 优先从子类获取 @SysLog：
     * 1，若子类重写了该方法，有标记就记录日志，没标记就忽略日志
     * 2，若子类没有重写该方法，就从父类获取，父类有标记就记录日志，没标记就忽略日志
     */
    public static ApiIgnore getTargetAnnotation(JoinPoint point) {
        try {
            ApiIgnore annotation = null;
            if (point.getSignature() instanceof MethodSignature) {
                Method method = ((MethodSignature) point.getSignature()).getMethod();
                if (method != null) {
                    annotation = method.getAnnotation(ApiIgnore.class);
                }
            }
            return annotation;
        } catch (Exception e) {
            log.warn("获取 {}.{} 的 @ApiIgnore 注解失败", point.getSignature().getDeclaringTypeName(), point.getSignature().getName(), e);
            return null;
        }
    }
}
